const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Smart Contracts", function () {
  let Currency, currency, Task, task, owner, addr1, addr2;

  beforeEach(async function () {
    [owner, addr1, addr2] = await ethers.getSigners();

    // 部署 CurrencyBrokers 合约
    const CurrencyBrokers = await ethers.getContractFactory("CurrencyBrokers");
    const currencyBrokers = await CurrencyBrokers.deploy();
    await currencyBrokers.deployed();

    // 部署 Currency 合约
    Currency = await ethers.getContractFactory("Currency");
    currency = await Currency.deploy(currencyBrokers.address);
    await currency.deployed();

    // 部署 Message 合约
    const Message = await ethers.getContractFactory("Message");
    const message = await Message.deploy();
    await message.deployed();

    // 部署 TaskEvaluation 合约
    const TaskEvaluation = await ethers.getContractFactory("TaskEvaluation");
    const taskEvaluation = await TaskEvaluation.deploy(addr1.address);
    await taskEvaluation.deployed();

    // 部署 HelperInformation 合约
    const HelperInformation = await ethers.getContractFactory("HelperInformation");
    const helperInformation = await HelperInformation.deploy();
    await helperInformation.deployed();

    // 部署 Task 合约
    Task = await ethers.getContractFactory("Task");
    task = await Task.deploy(
      message.address,
      currencyBrokers.address,
      taskEvaluation.address,
      helperInformation.address
    );
    await task.deployed();
  });

  it("should deploy Currency and Task contracts", async function () {
    expect(currency.address).to.properAddress;
    expect(task.address).to.properAddress;
  });

  it("should allow owner to publish a task", async function () {
    await task.publishTask(addr1.address, 0);
    const taskDetail = await task.tasks(0);
    expect(taskDetail.taskContent.numberOfTasks).to.equal(10);
  });

  it("should allow user to accept a task", async function () {
    await task.publishTask(addr1.address, 0);
    await task.connect(addr1).acceptTask(0);
    const taskDetail = await task.tasks(0);
    expect(taskDetail.status).to.equal(1); // TaskStatus.Accepted
  });

  it("should allow user to finish a task", async function () {
    await task.publishTask(addr1.address, 0);
    await task.connect(addr1).acceptTask(0);
    await task.connect(addr1).finishTask([1], 0);
    const taskDetail = await task.tasks(0);
    expect(taskDetail.status).to.equal(2); // TaskStatus.Completed
  });

  it("should allow owner to evaluate a task", async function () {
    await task.publishTask(addr1.address, 0);
    await task.connect(addr1).acceptTask(0);
    await task.connect(addr1).finishTask([1], 0);
    await task.evaluateTask(0);
    const taskDetail = await task.tasks(0);
    expect(taskDetail.status).to.equal(2); // TaskStatus.Completed
  });
});